home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-09-09 | 16.6 KB | 552 lines | [TEXT/CWIE] |
- // Simple framework for Macintosh sample code
- //
- // David Hayward and Nick Thompson
- // Developer Technical Support
- // AppleLink: DEVSUPPORT
- //
- // Copyrite 1995, Apple Computer,Inc
- //
- // This file contains the classic quickdraw printing sample code
- //
- // 10/4/94 nick first cut
-
-
- #include <Resources.h>
- #include <Errors.h>
- #include <TextUtils.h>
-
- #include "qdPrintUtils.h"
- #include "cursorUtils.h"
-
-
- /**\
- |**| ==============================================================================
- |**| PUBLIC GLOBALS
- |**| ==============================================================================
- \**/
- Boolean gPrGeneral_available = false ;
- long gPrOpenCount = 0 ;
-
-
- /**\
- |**| ==============================================================================
- |**| PRIVATE FUNCTION PROTOTYPES
- |**| ==============================================================================
- \**/
- pascal void IdleProc ( void ) ;
- OSErr CommandPeriod ( void ) ;
- void MyPrOpen ( void ) ;
- void MyPrClose ( void ) ;
- void UpdateStatusDialog ( QDPrintLoopParamsPtr params ) ;
-
-
- /**\
- |**| ==============================================================================
- |**| PUBLIC FUNCTIONS
- |**| ==============================================================================
- \**/
-
-
- /*------------------------------------------------------------------------------*\
- QDPrinting_available
- *------------------------------------------------------------------------------*
- This function returns noErr if the QuickDraw printing is
- available to the application and returns an appropriate err otherwise.
- It also checks to see if PrGeneral is available and returns an
- appropriate err otherwise.
- \*------------------------------------------------------------------------------*/
- OSErr QDPrinting_available ( void )
- {
- OSErr err ;
- TGetRslBlk getResRec ;
-
- MyPrOpen() ;
-
- err = PrError() ;
- if ( err == fnfErr ) // Here, "file not found" really means "no printer chosen."
- err = noPrinterChosenErr ;
- if ( err ) return err ;
-
- getResRec.iOpCode = getRslDataOp;
- PrGeneral((Ptr) &getResRec) ;
- err = PrError() ;
-
- MyPrClose() ;
-
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- GetDefaultTHPrint
- *------------------------------------------------------------------------------*
- This routine returns a default print handle for the current printer driver.
- The printer driver is expected to be closed upon entry, and is therefore
- opened and closed in this routine.
- \*------------------------------------------------------------------------------*/
- OSErr GetDefaultTHPrint (THPrint *hPrint)
- {
- OSErr err ;
-
- err = QDPrinting_available() ;
- if ( err ) return err ;
-
- // Create a handle, open the printer driver, set the
- // default values for the handle, and close the driver.
- // Be on the lookout for errors.
-
- *hPrint = (THPrint) NewHandle(sizeof(TPrint)) ;
- if (*hPrint == nil)
- return MemError() ;
-
- MyPrOpen() ;
- PrintDefault(*hPrint) ;
- err = PrError() ;
- MyPrClose() ;
-
- if ( err )
- {
- DisposeHandle( (Handle)*hPrint ) ;
- *hPrint = nil ;
- }
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- LoadResourceTHPrint
- *------------------------------------------------------------------------------*
- This routine loads a print handle resource with the resType r_printHdlType
- If there is no print record resource in the indicated resource file,
- the function returns resNotFound.
- Upon entry, hPrint is expected to be a valid print handle or nil.
- The printer driver is expected to be closed upon entry,and is therefore
- opened and closed in this routine.
- \*------------------------------------------------------------------------------*/
- OSErr LoadResourceTHPrint ( THPrint *hPrint, FSSpec *spec )
- {
- short savedRefNum;
- short resRefNum;
- Handle resHandle;
- OSErr err = noErr ;
- Boolean changed = false ;
-
- resRefNum = FSpOpenResFile( spec, fsRdPerm) ;
- if (resRefNum == -1)
- return fnfErr ;
-
- savedRefNum = CurResFile() ; // Save the current resource file refNum
- UseResFile(resRefNum) ; // set the current res file
-
- // Get our resource, if there is one
- resHandle = Get1IndResource(r_printHdlType,1) ;
- if ( resHandle==nil )
- err = ResError() ;
- else
- {
- if (*hPrint) // If we previously had a print handle
- DisposeHandle( (Handle)*hPrint ) ; // dispose of it before passing this new one back
- *hPrint = (THPrint) resHandle;
- HandToHand( (Handle*)hPrint ) ;
- MyPrOpen() ;
- changed = PrValidate( *hPrint ) ; // check we have a "good" print record
- MyPrClose() ;
- }
-
- if ( resHandle) ReleaseResource( resHandle ) ;
- CloseResFile( resRefNum ) ;
- UseResFile( savedRefNum ) ; // switch back to the original resource file.
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- SaveResourceTHPrint
- *------------------------------------------------------------------------------*
- This routine saves the passed print handle in resource fork of the
- indicated file. If there are already a print record resources, they are
- deleted and replaced.
- \*------------------------------------------------------------------------------*/
- OSErr SaveResourceTHPrint ( THPrint hPrint, FSSpec *spec )
- {
- short savedRefNum, uniqID;
- OSErr err = noErr ;
- Handle oldHdl;
- short resRefNum;
-
- resRefNum = FSpOpenResFile( spec, fsWrPerm) ;
- if (resRefNum == -1)
- return fnfErr ;
-
- // Make a copy of the hPrint handle.
- oldHdl = (Handle)hPrint ; // this is needed because CloseResFile
- err = HandToHand( &oldHdl ); // will dispose of the handle later
-
- if (!err)
- {
- savedRefNum = CurResFile() ; // Save the current resource file refNum
- UseResFile(resRefNum) ; // set the current res file
-
- // remove any existing resources
- while ( (oldHdl=Get1IndResource(r_printHdlType,1)) != nil )
- {
- RemoveResource(oldHdl) ; // remove the resource from the file
- DisposeHandle(oldHdl) ; // free the handle that is left behind
- }
-
- // Save the new resource with a unique ID.
- uniqID = Unique1ID( r_printHdlType ) ;
- AddResource( oldHdl, r_printHdlType, uniqID, "\p") ;
- err = ResError() ;
-
- UseResFile(savedRefNum) ; // switch back to the original resource file.
- }
-
- CloseResFile( resRefNum ) ;
- FlushVol( nil , spec->vRefNum ) ;
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- QDGetPageSize
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- OSErr QDGetPageSize ( THPrint hPrint, Rect *pageRect )
- {
- *pageRect = (**hPrint).prInfo.rPage ;
- return noErr ;
- }
-
-
-
- /*------------------------------------------------------------------------------*\
- QDStyleDlog
- *------------------------------------------------------------------------------*
- This routine displays the standard Page Setup dialog
- \*------------------------------------------------------------------------------*/
- OSErr QDStyleDlog( THPrint hPrint )
- {
- OSErr err = noErr ;
- Boolean changed = false ;
-
- MyPrOpen() ;
- err = PrError() ;
-
- if( !err )
- {
- changed = PrStlDialog(hPrint) ;
- err = PrError() ;
- if (!err && !changed) err = iPrAbort ;
- }
-
- MyPrClose() ;
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- QDJobDlog
- *------------------------------------------------------------------------------*
- This routine displays the standard Print dialog
- \*------------------------------------------------------------------------------*/
- OSErr QDJobDlog (THPrint hPrint)
- {
- OSErr err = noErr ;
- Boolean changed = false ;
-
- MyPrOpen() ;
- err = PrError() ;
-
- if ( !err )
- {
- changed = PrJobDialog(hPrint) ;
- err = PrError() ;
- if ( !err && !changed ) err = iPrAbort;
- }
-
- MyPrClose() ;
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- QDPrintLoopBegin
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- OSErr QDPrintLoopBegin ( QDPrintLoopParamsPtr params )
- {
- OSErr err ;
- long jobFirst, jobLast ;
- Str255 title ;
- PrIdleUPP idleUPP=nil ;
- GrafPtr savedPort ;
-
- GetPort( &savedPort ) ;
-
- MyPrOpen() ;
- err = PrError() ;
- if ( err ) goto PROpenFailed ;
-
- // we don't assign this directly because NewPrIdleProc may move memory,
- // so assign to an intermediate variable idleUPP
- idleUPP = NewPrIdleProc(IdleProc) ;
- (**(params->hPrint)).prJob.pIdleProc = idleUPP ;
-
- // Determine which pages the user selected to print.
- // If the user specifies a range that is greater than the actual number
- // of pages, then only print those pages that are in the document.
- jobFirst = (**(params->hPrint)).prJob.iFstPage ;
- jobLast = (**(params->hPrint)).prJob.iLstPage ;
- if (jobFirst > params->firstPage) params->firstPage = jobFirst;
- if (jobLast < params->lastPage ) params->lastPage = jobLast;
-
- // dialog stuff
- params->currentPage = params->firstPage - 1 ; // make curPage out of range
- params->statusDialog = GetNewDialog( 1005, nil, (WindowRef)-1 );
- GetWTitle( params->window, title ) ;
- UpdateStatusDialog( params ) ;
- ShowWindow( (WindowRef)(params->statusDialog) ) ;
-
- // begin printing if there are no errors.
- params->printingPort = (GrafPtr)PrOpenDoc( params->hPrint, nil, nil ) ;
- err = PrError() ;
- if ( err ) goto PROpenDocFailed;
-
- return noErr ;
-
-
- PROpenDocFailed:
- MyPrClose() ;
-
- PROpenFailed:
- if (idleUPP) DisposeRoutineDescriptor( (UniversalProcPtr)idleUPP ) ;
- DisposeDialog( params->statusDialog ) ;
- SetPort( savedPort ) ;
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- QDPrintLoopPageBefore
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- OSErr QDPrintLoopPageBefore ( QDPrintLoopParamsPtr params )
- {
- OSErr err ;
-
- // update dialog
- UpdateStatusDialog( params ) ;
-
- SetPort( params->printingPort ) ;
- PrOpenPage( (TPPrPort)(params->printingPort), nil ) ;
- err = PrError() ;
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- QDPrintLoopPageAfter
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- OSErr QDPrintLoopPageAfter ( QDPrintLoopParamsPtr params )
- {
- OSErr err ;
-
- PrClosePage( (TPPrPort)(params->printingPort) ) ;
- err = PrError() ;
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- QDPrintLoopEnd
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- OSErr QDPrintLoopEnd ( QDPrintLoopParamsPtr params )
- {
- OSErr err ;
- PrIdleUPP idleUPP ;
- TPrStatus theStatus ;
-
- // update dialog
- UpdateStatusDialog( params ) ;
-
- PrCloseDoc( (TPPrPort)(params->printingPort) ) ;
- err = PrError() ;
-
- // if we're printing to our good friend the ImageWriter, or similar, despool
- if( ( !err ) && ((**(params->hPrint)).prJob.bJDocLoop == bSpoolLoop))
- PrPicFile( params->hPrint, nil, nil, nil, &theStatus ) ;
-
- PrClose() ;
-
- // Dispose IdleProc UPP
- idleUPP = (**(params->hPrint)).prJob.pIdleProc ;
- DisposeRoutineDescriptor( (UniversalProcPtr)idleUPP ) ;
-
- // Dispose Dialog
- DisposeDialog( params->statusDialog ) ;
-
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- DoQDPrintLoop
- *------------------------------------------------------------------------------*
- This is a basic classic QD print loop
- \*------------------------------------------------------------------------------*/
- /*OSErr DoQDPrintLoop ( THPrint hPrint, long firstPage, long lastPage, winHandle win )
- {
- OSErr err ;
- GrafPtr savedPort ;
- QDPrintLoopParamsRec params ;
-
- GetPort( &savedPort ) ;
-
- params.hPrint = hPrint ;
- params.window = GetWinWindow(win) ;
- params.firstPage = firstPage ;
- params.lastPage = lastPage ;
-
- err = QDPrintLoopBegin( ¶ms ) ;
- if (err) return err ;
-
- for ( params.currentPage = params.firstPage;
- params.currentPage <= params.lastPage && !err ;
- params.currentPage ++ )
- {
- if (!err) err = QDPrintLoopPageBefore( ¶ms ) ;
- if (!err) err = CallWinPagePrintProc( win, params.printingPort, params.currentPage ) ;
- if (!err) err = QDPrintLoopPageAfter( ¶ms ) ;
- }
-
- err = QDPrintLoopEnd( ¶ms ) ;
- SetPort( savedPort ) ;
- return err ;
- }*/
-
-
- /**\
- |**| ==============================================================================
- |**| PRIVATE FUNCTIONS
- |**| ==============================================================================
- \**/
-
-
- /*------------------------------------------------------------------------------*\
- MyPrOpen
- *------------------------------------------------------------------------------*
- This routine allows nested calls to PrOpen/PrClose be keeping track of
- the number of calls that have been made in the global gPrOpenCount.
- It does not return any error so you still need to call PrError ofter this.
- \*------------------------------------------------------------------------------*/
- static void MyPrOpen ( void )
- {
- if ( gPrOpenCount==0 ) // if we haven't called it yet
- PrOpen() ; // open it
- gPrOpenCount++ ; // increment the count
- }
-
-
- /*------------------------------------------------------------------------------*\
- MyPrClose
- *------------------------------------------------------------------------------*
- This routine allows nested calls to PrOpen/PrClose be keeping track of
- the number of calls that have been made in the global gPrOpenCount.
- \*------------------------------------------------------------------------------*/
- static void MyPrClose ( void )
- {
- gPrOpenCount-- ; // increment the count
- if ( gPrOpenCount==0 ) // if the count is down to zero
- PrClose() ; // close it
- }
-
-
- /*------------------------------------------------------------------------------*\
- IdleProc
- *------------------------------------------------------------------------------*
- This routine is a PrIdleProcPtr that spins our cursor and looks for
- command-period presses during printing.
- \*------------------------------------------------------------------------------*/
- static pascal void IdleProc ( void )
- {
- OSErr err ;
-
- BumpCursor() ;
- err = CommandPeriod() ;
- if ( err ) PrSetError( err ) ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- CommandPeriod
- *------------------------------------------------------------------------------*
- This routine checks to see if the user has pressed command-period.
- The Printing Manager does this for us, but a routine like this is helpful
- to allow users to cancel in the middle of a rendering routine, rather
- than only Printing Manager operations.
- If there's a command-period in the event queue, the routine returns
- iPrAbort just like the Printing Manager. Otherwise, it returns noErr
- \*------------------------------------------------------------------------------*/
- static OSErr CommandPeriod ( void )
- {
- Boolean userCancel = false ;
- short itemHit ;
- short eventMask = keyDownMask|autoKeyMask|mDownMask ;
- EventRecord evtRec ;
- WindowRef window ;
-
- if ( WaitNextEvent( eventMask, &evtRec, 0, nil) )
- {
- switch (evtRec.what)
- {
- case autoKey:
- case keyDown:
- userCancel = (evtRec.modifiers & cmdKey) &&
- ((evtRec.message & charCodeMask) == '.') ;
- break ;
-
- case mouseDown:
- if ( IsDialogEvent(&evtRec))
- if ( FindWindow(evtRec.where,&window) == inContent )
- // should confirm it is our dialog here
- if ( DialogSelect(&evtRec,(DialogPtr*)&window,&itemHit) )
- userCancel = (itemHit == kStdCancelItemIndex ) ;
- break ;
- }
- }
- return ( (userCancel) ? (iPrAbort) : (noErr) ) ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- UpdateStatusDialog
- *------------------------------------------------------------------------------*
- This routine
- \*------------------------------------------------------------------------------*/
- static void UpdateStatusDialog ( QDPrintLoopParamsPtr params )
- {
- long cPage, fPage, lPage ;
- Str255 strA, strC, strD ;
-
- cPage = params->currentPage ;
- fPage = params->firstPage ;
- lPage = params->lastPage ;
-
- if ( ( cPage>=fPage ) && ( cPage<=lPage ) )
- {
- GetWTitle( params->window, strA ) ;
- NumToString( cPage - fPage +1, strC);
- NumToString( lPage - fPage +1, strD);
- ParamText( strA, "\pprinter", strC, strD ) ;
- ShowDialogItem( params->statusDialog, 4 ) ;
- }
- else
- HideDialogItem( params->statusDialog, 4 ) ;
-
- DrawDialog( params->statusDialog ) ;
- }
-
-